import async from 'async';
import redis from 'redis';
import moduleMain from './main';
import moduleHash from './hash';
import moduleSets from './sets';
import moduleSorted from './sorted';
import moduleList from './list';
import log from '../../log';

/* eslint-disable */
const noop = () => {
};

const redisModule = module.exports;


redisModule.init = (options, callback = noop) => {
    redisModule.client = redisModule.connect(options);
    moduleMain(redisModule.client, redisModule);
    moduleHash(redisModule.client, redisModule);
    moduleSets(redisModule.client, redisModule);
    moduleSorted(redisModule.client, redisModule);
    moduleList(redisModule.client, redisModule);
    callback();
};

/*redisModule.initSessionStore = function (callback) {
 var meta = require('../meta');
 var sessionStore = require('connect-redis')(session);

 redisModule.sessionStore = new sessionStore({
 client: redisModule.client,
 ttl: meta.getSessionTTLSeconds(),
 });

 if (typeof callback === 'function') {
 callback();
 }
 };*/

redisModule.connect = (options = {}) => {
    options.options = options.options || {};
    if (options.password) {
        options.options.auth_pass = options.password;
    }

    const cxn = options.host && options.host.indexOf('/') >= 0
        /* If redis.host contains a path name character, use the unix dom sock connection. ie, /tmp/redis.sock */
        ? redis.createClient(options.host, options.options)
        /* Else, connect over tcp/ip */
        : redis.createClient(options.port, options.host, options.options);

    cxn.on('error', (err) => {
        log.error(err.stack);
        //process.exit(1);
    });

    if (options.password) {
        cxn.auth(options.password);
    }

    const dbIdx = parseInt(options.database, 10);
    if (dbIdx >= 0) {
        cxn.select(dbIdx, (err) => {
            if (err) {
                log.error(`NodeBB could not connect to your Redis database. Redis returned the following error:${err.message}`);
                //process.exit();
            }
        });
    }

    return cxn;
};

redisModule.createIndices = (callback) => {
    setImmediate(callback);
};

redisModule.checkCompatibility = (callback) => {
    async.waterfall([
        function (next) {
            redisModule.info(redisModule.client, next);
        },
        function (info, next) {
            redisModule.checkCompatibilityVersion(info.redis_version, next);
        },
    ], callback);
};


redisModule.close = (callback) => {
    callback = callback || noop;
    redisModule.client.quit(callback);
};

redisModule.info = (cxn, callback) => {
    if (!cxn) {
        return callback();
    }
    async.waterfall([
        function (next) {
            cxn.info(next);
        },
        function (data, next) {
            const lines = data.toString().split('\r\n').sort();
            const redisData = {};
            lines.forEach((line) => {
                const parts = line.split(':');
                if (parts[1]) {
                    redisData[parts[0]] = parts[1];
                }
            });
            redisData.used_memory_human = (redisData.used_memory / (1024 * 1024 * 1024)).toFixed(2);
            redisData.raw = JSON.stringify(redisData, null, 4);
            redisData.redis = true;

            next(null, redisData);
        },
    ], callback);
};

redisModule.helpers = redisModule.helpers || {};
redisModule.helpers.redis = require('./helpers');
/* eslint-enable */
